home *** CD-ROM | disk | FTP | other *** search
- /* Fchart - fcmd.c */
- /*
- * Gnuplot code
- * Copyright (C) 1986, 1987, 1990 Thomas Williams, Colin Kelley
- *
- * Permission to use, copy, and distribute this software and its
- * documentation for any purpose with or without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.
- *
- * Permission to modify the software is granted, but not the right to
- * distribute the modified code. Modifications are to be distributed
- * as patches to released version.
- *
- * This software is provided "as is" without express or implied warranty.
- *
- *
- * AUTHORS
- *
- * Original Software:
- * Thomas Williams, Colin Kelley.
- *
- * Gnuplot 2.0 additions:
- * Russell Lang, Dave Kotz, John Campbell.
- *
- * Fchart changes and additions:
- * Piotr Filip Sawicki
- *
- * send your comments or suggestions to fs@uwasa.fi
- *
- */
- #include <stdio.h>
- #include <math.h>
- #include <ctype.h>
-
- #ifdef MSDOS
- #include <process.h>
-
- #ifdef __ZTC__
- #define P_WAIT 0
- #include <time.h> /* usleep() */
- #else
-
- #ifdef __TURBOC__
- #include <dos.h> /* sleep() */
-
- #else /* must be MSC */
- #include <time.h> /* kludge to provide sleep() */
- void sleep(); /* defined later */
- #endif /* TURBOC */
- #endif /* ZTC */
-
- #endif /* MSDOS */
-
- #include "plot.h"
- #include "fchart.h"
- #include "help.h"
-
- #ifndef STDOUT
- #define STDOUT 1
- #endif
-
- #ifndef HELPFILE
- #define HELPFILE "fchart.gih" /* changed by makefile */
- #endif
-
- /* global defs for default values */
- #define DEF_T_FORMAT "%g" /* make it as narrow as possible */
- #define EXPL_RAD 0.3 /* ratio of explosion of a slice */
- #define MAXBARWIDTH 0.2 /* default maximal allowable width of bar */
- #define INTERBAR 0.2 /* interbar space in terms of real bar width */
- #define INTERGROUP 0.5 /* space between groups of bars */
- #define OTHER "other" /* name for combined slice */
-
- /*
- * global variables to hold status of 'set' options
- *
- */
-
- BOOLEAN autoscale = TRUE,
- auto_label = FALSE,
- p_clockwise = TRUE,
- b_clockwise = TRUE,
- draw_border = TRUE;
-
- enum DRAW_STYLE data_style = ABARS;
- enum GRAV_DIR gravity = SOUTH,
- explode = DEFAULT;
- enum INP_STYLE inp_style = PRIVATE;
- enum FONT_STYLE vect_font = F_WHENN;
- BOOLEAN log_y = FALSE;
- FILE* outfile;
- char outstr[MAX_LINE_LEN+1] = "STDOUT";
- int samples = SAMPLES;
- int term = 0; /* unknown term is 0 */
- int xmin = -1,
- xmax = -1;
- double base = 0.0;
- double loff = 0.0,
- roff = 0.0,
- toff = 0.0,
- boff = 0.0;
- double b_wid = MAXBARWIDTH,
- b_int = INTERBAR,
- b_spc = INTERGROUP;
- double radexp = EXPL_RAD; /* explosion power */
- double zero = ZERO; /* zero threshold, not 0! */
- int HLitem = HL_NON; /* no highliting by default */
- struct pair data_place = { -1, -1 }, /* not defined yet */
- label_plac = { -1, -1 }; /* not defined yet */
- float xsize = 1.0,
- ysize = 1.0;
- double treshold = 0.0;
- char thrname[MAX_LINE_LEN+1] = OTHER;
- char tic_form[MAX_LINE_LEN+1] = DEF_T_FORMAT;
- int strunc = -1;
-
- struct dfile data_head = { NULL, 0.0, 0.0, 0, 0, HL_NON, FALSE, NULL, NULL } ;
-
- BOOLEAN screen_ok;
- BOOLEAN term_init;
- /* BOOLEAN undefined; */ /* probably not even used */
-
- /*
- * instead of <strings.h>
- */
-
- char *gets(),*getenv(),*sprintf(); /* for lint only */
- char *strcpy(),*strncpy(),*strcat();
-
- extern double real();
- extern void set_label(), set_nolabel(), set_arrow(), set_noarrow();
- extern void show_labels(), show_arrow();
-
- extern struct termentry term_tbl[];
-
- struct lexical_unit token[MAX_TOKENS];
- char input_line[MAX_LINE_LEN+1] = "";
- int num_tokens, c_token;
-
- static char replot_line[MAX_LINE_LEN+1];
- static int plot_token; /* start of 'plot' command */
-
- extern void squash_spaces(), lower_case();
-
- com_line()
- {
- read_line(PROMPT);
-
- screen_ok = interactive; /* see 'Gnuplot' why */
-
- do_line();
- }
-
-
- do_line() /* also used in load_file */
- {
- if (is_system(input_line[0])) {
- do_system();
- fputs("!\n",stderr);
- return;
- }
- num_tokens = scanner(input_line);
- c_token = 0;
- while(c_token < num_tokens) {
- command();
- if (c_token < num_tokens) /* something after command */
- if (equals(c_token,";"))
- c_token++;
- else
- int_error("';' expected",c_token);
- }
- }
-
- command()
- {
- static char sv_file[MAX_LINE_LEN+1];
- /* string holding name of save or load file */
-
- if (equals(c_token,"help") || equals(c_token,"?")) {
- c_token++;
- do_help();
- }
- else if (almost_equals(c_token,"test")) {
- c_token++;
- term_test();
- }
- else if (almost_equals(c_token,"pa$use")) {
- int stime=1, text=0;
- char buf[MAX_LINE_LEN+1];
-
- c_token++;
- if (equals(c_token,"-")) stime=-1, c_token++;
- stime *= (int)real(c_token);
- c_token++;
- if (!(END_OF_COMMAND)) {
- if (!isstring(c_token))
- int_error("expecting string",c_token);
- else {
- quote_str(buf,c_token);
- fprintf (stderr, "%s",buf);
- text = 1;
- }
- }
- if (stime < 0) fgets (buf,MAX_LINE_LEN,stdin); /* Hold until CR hit */
- #ifdef __ZTC__
- if (stime > 0) usleep((unsigned long) stime);
- #else
- if (stime > 0) sleep((unsigned) stime);
- #endif
- if (text != 0 && stime >= 0) fprintf (stderr,"\n");
- c_token++;
- screen_ok = FALSE;
- }
- else if (almost_equals(c_token,"p$lot") ||
- almost_equals(c_token,"d$raw")) {
- plot_token = c_token++;
- plotrequest(FALSE);
- }
- else if (almost_equals(c_token,"tp$lot") ||
- almost_equals(c_token,"td$raw") ||
- almost_equals(c_token,"xp$lot") || /* for backward compatibility */
- almost_equals(c_token,"xd$raw") || /* for backward compatibility */
- almost_equals(c_token,"trans_plot") ||
- almost_equals(c_token,"trans_draw")) {
- plot_token = c_token++;
- plotrequest(TRUE);
- }
- else if (almost_equals(c_token,"rep$lot") ||
- almost_equals(c_token,"red$raw")) {
- c_token++;
- if (replot_line[0] == '\0')
- int_error("no previous plot",c_token);
- if (!END_OF_COMMAND) {
- char str[MAX_LINE_LEN+1];
- capture(str,c_token,num_tokens-1);
- if ((strlen(str)+strlen(input_line)) <= MAX_LINE_LEN-1) {
- (void) strcat(replot_line,",");
- (void) strcat(replot_line,str);
- }
- else
- int_error("plot line too long with replot arguments",c_token);
- }
- (void) strcpy(input_line,replot_line);
- screen_ok = FALSE;
- num_tokens = scanner(input_line);
- c_token = 1; /* skip the 'plot' part */
- plotrequest(almost_equals(0,"td$raw") ||
- almost_equals(0,"tp$lot") ||
- almost_equals(0,"xd$raw") ||
- almost_equals(0,"xp$lot") ||
- almost_equals(0,"tr$ans_plot") ||
- almost_equals(0,"tr$ans_draw")); /* fetch plot type */
- }
- else if (almost_equals(c_token,"se$t"))
- set_stuff();
- else if (almost_equals(c_token,"sh$ow"))
- show_stuff();
- else if (almost_equals(c_token,"sa$ve")) {
- c_token++;
- if (END_OF_COMMAND || !isstring(c_token))
- int_error("name of file expected", c_token);
- quote_str(sv_file,c_token);
- save_sets(fopen(sv_file,"w"));
- /* c_token updated in save_sets */
- }
- else if (almost_equals(c_token,"cl$ear")) {
- if (!term_init) {
- (*term_tbl[term].init)();
- term_init = TRUE;
- }
- (*term_tbl[term].graphics)();
- (*term_tbl[term].text)();
- (void) fflush(outfile);
- screen_ok = FALSE;
- c_token++;
- }
- else if (almost_equals(c_token,"she$ll")) {
- do_shell();
- screen_ok = FALSE;
- c_token++;
- }
- else if (almost_equals(c_token,"l$oad") ||
- almost_equals(c_token,"r$ead")) {
- if (!isstring(++c_token))
- int_error("expecting filename",c_token);
- else {
- quote_str(sv_file,c_token);
- load_file(fopen(sv_file,"r"));
- /* input_line[] and token[] now destroyed! */
- c_token = num_tokens = 0;
- }
- }
- else if (almost_equals(c_token,"ex$it") ||
- almost_equals(c_token,"q$uit")) {
- done(IO_SUCCESS);
- }
- else if (!equals(c_token,";")) { /* null statement */
- int_error("Invalid command. Try:\n\
- '?/help', 'test', 'pause', '[t]draw/[t]plot',\n\
- 'replot/redraw', 'set', 'show', 'save', 'shell',\n\
- 'load/read', 'exit/quit'",c_token);
- }
- }
-
-
- enum DRAW_STYLE
- get_style()
- {
- register enum DRAW_STYLE ps;
-
- c_token++;
- if (almost_equals(c_token,"a$djacent_bars"))
- ps = ABARS;
- else if (almost_equals(c_token,"l$ayer_bars"))
- ps = LAYB;
- else if (almost_equals(c_token,"s$tacked_bars"))
- ps = SBAR;
- else if (almost_equals(c_token,"p$iechart"))
- ps = PIECHART;
- else
- int_error("expecting 'adjacent_bars', 'stacked_bars', 'layer_bars' or 'piechart'",c_token);
- c_token++;
- return(ps);
- }
-
- enum GRAV_DIR
- get_gravity()
- {
- c_token++;
- if (END_OF_COMMAND) return(DEFAULT);
- else if (almost_equals(c_token,"b$ottom") || almost_equals(c_token,"s$outh")) {
- c_token++;
- return(SOUTH);
- }
- else if (almost_equals(c_token,"t$op") || almost_equals(c_token,"n$orth")) {
- c_token++;
- return(NORTH);
- }
- else if (almost_equals(c_token,"l$eft") || almost_equals(c_token,"w$est")) {
- c_token++;
- return(WEST);
- }
- else if (almost_equals(c_token,"r$ight") || almost_equals(c_token,"e$ast")) {
- c_token++;
- return(EAST);
- }
- else
- int_error("expecting direction: 'left/west', 'right/east',\n'bottom/south' or 'top/north'",c_token);
- /*NOTREACHED*/
- }
-
- enum INP_STYLE
- get_input()
- {
- if (END_OF_COMMAND) return(PRIVATE);
- else if (almost_equals(c_token,"g$nuplot")) {
- c_token++;
- return(GNUPLOT);
- }
- else if (almost_equals(c_token,"p$rivate")) {
- c_token++;
- return(PRIVATE);
- }
- else if (almost_equals(c_token,"c$ustomized")) {
- c_token++;
- return(CUSTOMD);
- }
- else
- int_error("expected 'gnuplot', 'private' or 'customized'",c_token);
- /*NOTREACHED*/
- }
-
- set_stuff()
- {
- static char testfile[MAX_LINE_LEN+1];
-
- if (almost_equals(++c_token,"b$ar")) {
- set_bar_stuff();
- }
- else if (almost_equals(c_token,"fr$ame")) {
- draw_border = TRUE;
- c_token++;
- }
- else if (almost_equals(c_token,"nof$rame")) {
- draw_border = FALSE;
- c_token++;
- }
- else if (almost_equals(c_token,"for$mat")) {
- c_token++;
- if (END_OF_COMMAND)
- (void) strcpy(tic_form, DEF_T_FORMAT);
- else if (!isstring(c_token))
- int_error("enquoted format expected", c_token);
- else
- quote_str(tic_form, c_token++);
- }
- else if (almost_equals(c_token,"fon$t")) {
- c_token++;
- if (END_OF_COMMAND)
- vect_font = F_ALWYS;
- else {
- if (almost_equals(c_token,"n$ever"))
- vect_font = F_NEVER;
- else if (almost_equals(c_token,"w$hen_needed"))
- vect_font = F_WHENN;
- else if (almost_equals(c_token,"r$otated"))
- vect_font = F_ROTAT;
- else if (almost_equals(c_token,"a$lways"))
- vect_font = F_ALWYS;
- else
- int_error("'never', 'when_needed', 'rotated', or 'always' expected",c_token);
- c_token++;
- }
- }
- else if (almost_equals(c_token,"au$tolabeling")) {
- auto_label = TRUE;
- c_token++;
- }
- else if (almost_equals(c_token,"noau$tolabeling")) {
- auto_label = FALSE;
- c_token++;
- }
- else if (almost_equals(c_token,"ar$row")) {
- c_token++;
- set_arrow(TRUE);
- }
- else if (almost_equals(c_token,"noar$row")) {
- c_token++;
- set_noarrow();
- }
- else if (almost_equals(c_token,"c$ustomized")) {
- c_token++;
- if (END_OF_COMMAND) {
- data_place.from = -1; /* not defined */
- label_plac.from = -1; /* thus no label */
- }
- else {
- if (!equals(c_token,"["))
- int_error("expecting '['",c_token);
- c_token++;
- load_range(&data_place.from,&data_place.upto);
- if (!equals(c_token,"]"))
- int_error("expecting ']'",c_token);
- c_token++;
- if (END_OF_COMMAND)
- label_plac.from = -1; /* no label */
- else {
- if (equals(c_token,",")) c_token++; /* optional ',' */
- if (!equals(c_token,"["))
- int_error("expecting '['",c_token);
- c_token++;
- load_range(&label_plac.from,&label_plac.upto);
- if (!equals(c_token,"]"))
- int_error("expected ']'",c_token);
- c_token++;
- }
- if (!check_ranges(&data_place,&label_plac)) { /* overlapping ranges ? */
- data_place.from = label_plac.from = -1;
- int_error("value and label places are overlapping or are empty",NO_CARET);
- }
- }
- }
- else if (almost_equals(c_token,"h$ighlight")) {
- c_token++;
- HLitem = get_HL();
- }
- else if (almost_equals(c_token,"i$nput")) {
- c_token++;
- inp_style = get_input();
- }
- else if (almost_equals(c_token,"lo$gscale")) {
- c_token++;
- log_y = TRUE;
- }
- else if (almost_equals(c_token,"nolo$gscale")) {
- log_y = FALSE;
- c_token++;
- }
- else if (almost_equals(c_token,"la$bel")) {
- c_token++;
- set_label();
- }
- else if (almost_equals(c_token,"nola$bel")) {
- c_token++;
- set_nolabel();
- }
- else if (almost_equals(c_token,"li$ne")) {
- c_token++;
- set_arrow(FALSE);
- }
- else if (almost_equals(c_token,"noli$ne")) {
- c_token++;
- set_noarrow();
- }
- else if (almost_equals(c_token,"of$fsets")) {
- c_token++;
- if (END_OF_COMMAND) {
- loff = roff = toff = boff = 0.0; /* Reset offsets */
- }
- else {
- load_offsets (&loff,&roff,&toff,&boff);
- if ((loff>1.0 ? loff/100.0 : loff) + (roff>1.0 ? roff/100.0 : roff) >= 1.0 ||
- (boff>1.0 ? boff/100.0 : boff) + (toff>1.0 ? toff/100.0 : toff) >= 1.0) {
- loff = roff = toff = boff = 0.0; /* Reset offsets for the future */
- int_error("null picture size within given offsets",NO_CARET);
- }
- }
- }
- else if (almost_equals(c_token,"o$utput")) {
- register FILE *f;
-
- c_token++;
- if (END_OF_COMMAND) { /* no file specified */
- UP_redirect (4);
- if (outfile != stdout) /* Never close stdout */
- (void) fclose(outfile);
- outfile = stdout; /* Avoid the dup... */
- term_init = FALSE;
- (void) strcpy(outstr,"STDOUT");
- } else if (!isstring(c_token))
- int_error("expecting filename",c_token);
- else {
- quote_str(testfile,c_token);
- if (!(f = fopen(testfile,"w"))) {
- os_error("cannot open file; output not changed",c_token);
- }
- if (outfile != stdout) /* Never close stdout */
- (void) fclose(outfile);
- outfile = f;
- term_init = FALSE;
- outstr[0] = '\'';
- (void) strcat(strcpy(outstr+1,testfile),"'");
- UP_redirect (1);
- }
- c_token++;
- }
- else if (almost_equals(c_token,"p$ie")) {
- set_pie_stuff();
- }
- else if (almost_equals(c_token,"si$ze")) {
- c_token++;
- if (END_OF_COMMAND) {
- xsize = 1.0;
- ysize = 1.0;
- }
- else {
- xsize = (float)real(c_token);
- c_token++;
- if (!equals(c_token,","))
- int_error("',' expected",c_token);
- c_token++;
- if (END_OF_COMMAND)
- int_error("value for ysize expected",c_token);
- ysize = (float)real(c_token);
- c_token++;
- }
- }
- else if (almost_equals(c_token,"st$yle")) {
- data_style = get_style();
- }
- else if (almost_equals(c_token,"te$rminal")) {
- c_token++;
- if (END_OF_COMMAND) {
- list_terms();
- screen_ok = FALSE;
- }
- else {
- if (term && term_init) {
- (*term_tbl[term].reset)();
- (void) fflush(outfile);
- }
- term = set_term(c_token);
- c_token++;
- }
- }
- else if (almost_equals(c_token,"ti$tle")) {
- c_token++;
- if (END_OF_COMMAND) {
- if (data_head.fname)
- free(data_head.fname);
- data_head.fname = NULL;
- }
- else if (isstring(c_token)) {
- m_quote_capture(&(data_head.fname), c_token, c_token);
- c_token++;
- }
- else
- int_error("title within quotes expected", c_token);
- }
- else if (almost_equals(c_token,"tr$uncate")) {
- c_token++;
- if (END_OF_COMMAND)
- strunc = 0;
- else {
- strunc = real(c_token);
- c_token++;
- }
- }
- else if (almost_equals(c_token,"not$runcate")) {
- c_token++;
- strunc = -1;
- }
- else if (almost_equals(c_token,"r$ange")) {
- c_token++;
- if (END_OF_COMMAND) xmin=-1;
- else {
- if (!equals(c_token,"["))
- int_error("expecting '['",c_token);
- c_token++;
- load_range(&xmin,&xmax);
- if (!equals(c_token,"]"))
- int_error("expecting ']'",c_token);
- c_token++;
- if (xmax != -1 && xmax < xmin) {
- xmin = -1; /* whole */
- int_error("given range is empty",NO_CARET);
- }
- }
- }
- else if (almost_equals(c_token,"z$ero") ||
- almost_equals(c_token,"eps$ilon")) {
- int sign=1;
- c_token++;
- if (equals(c_token,"-")) sign=-1, c_token++;
- zero = sign*real(c_token);
- c_token++;
- }
- else
- int_error(
- "valid set options: 'bar', '[no]logscale',\n\
- 'customized', 'format', 'highlight', 'offsets'\n\
- 'output', 'pie', 'style', '[no]autolabeling',\n\
- 'terminal', 'title', 'range', 'zero/epsilon',\n\
- '[no]frame', 'font', '[no]truncate', '[no]label',\n\
- '[no]arrow', '[no]line'",
- c_token);
- }
-
- set_bar_stuff()
- {
- if (almost_equals(++c_token,"a$utoscale")) {
- autoscale = TRUE;
- c_token++;
- }
- else if (almost_equals(c_token,"noa$utoscale")) {
- autoscale = FALSE;
- c_token++;
- }
- else if (almost_equals(c_token,"b$ase")) {
- int sign = 1;
- c_token++;
- if (END_OF_COMMAND) base = 0.0;
- else {
- if (equals(c_token,"-")) c_token++, sign=-1;
- base = sign*real(c_token);
- c_token++;
- }
- }
- else if (almost_equals(c_token,"cl$ockwise")) {
- b_clockwise = TRUE;
- c_token++;
- }
- else if (almost_equals(c_token,"co$unter_clockwise")) {
- b_clockwise = FALSE;
- c_token++;
- }
- else if (almost_equals(c_token,"g$ravitation")) {
- gravity = get_gravity();
- if (gravity==DEFAULT) gravity = SOUTH;
- }
- else if (almost_equals(c_token,"w$idth")) {
- c_token++;
- if (END_OF_COMMAND) {
- b_wid = MAXBARWIDTH;
- b_int = INTERBAR;
- b_spc = INTERGROUP;
- }
- else
- load_offsets(&b_wid, &b_int, &b_spc, (double *) NULL);
- }
- else
- int_error("valid options: '[no]autoscale', 'base',\n\
- '[counter_]clockwise', 'gravitation', 'width'",c_token);
- }
-
- set_pie_stuff()
- {
- if (almost_equals(++c_token,"ex$plode")) {
- explode = get_gravity();
- }
- else if (almost_equals(c_token,"cl$ockwise")) {
- p_clockwise = TRUE;
- c_token++;
- }
- else if (almost_equals(c_token,"co$unter_clockwise")) {
- p_clockwise = FALSE;
- c_token++;
- }
- else if (almost_equals(c_token,"r$adius")) {
- c_token++;
- if (END_OF_COMMAND)
- radexp = EXPL_RAD;
- else {
- radexp = real(c_token);
- c_token++;
- }
- }
- else if (almost_equals(c_token,"s$amples")) {
- register int tsamp;
-
- c_token++;
- tsamp = (int)real(c_token);
- if (tsamp < 1)
- int_error("sampling rate must be > 0; sampling unchanged",
- c_token);
- else samples = tsamp;
- c_token++;
- }
- else if (almost_equals(c_token,"t$hreshold")) {
- c_token++;
- if (END_OF_COMMAND) {
- treshold = 0.0;
- strcpy(thrname, OTHER);
- }
- else {
- treshold = real(c_token);
- c_token++;
- if (END_OF_COMMAND)
- strcpy(thrname, OTHER);
- else if (!isstring(c_token))
- int_error("name in quotes expected", c_token);
- else {
- quote_str(thrname, c_token);
- c_token++;
- }
- }
- }
- else
- int_error("valid options: '[counter_]clockwise',\n\
- 'explode', 'radius', 'samples', 'threshold'",c_token);
- }
-
- get_HL()
- {
- if (END_OF_COMMAND) return(HL_NON);
- else if (almost_equals(c_token,"n$one")) {
- c_token++;
- return(HL_NON);
- }
- else if (almost_equals(c_token,"mi$nim")) {
- c_token++;
- return(HL_MIN);
- }
- else if (almost_equals(c_token,"ma$xim")) {
- c_token++;
- return(HL_MAX);
- }
- else if (isnumber(c_token)) {
- return((int) real(c_token++));
- }
- else
- int_error("'maximum', 'minimum', 'none' or number expected",c_token);
- /*NOTREACHED*/
- }
-
- show_stuff()
- {
- if (almost_equals(++c_token,"sc$ale")) {
- (void) putc('\n',stderr);
- show_autoscale();
- c_token++;
- }
- else if (almost_equals(c_token,"au$tolabeling")) {
- (void) putc('\n',stderr);
- show_label();
- c_token++;
- }
- else if (almost_equals(c_token,"lo$gscale")) {
- (void) putc('\n',stderr);
- show_logscale();
- c_token++;
- }
- else if (almost_equals(c_token,"la$bel")) {
- (void) putc('\n',stderr);
- c_token++;
- if (END_OF_COMMAND)
- show_labels(0, stderr, FALSE);
- else {
- show_labels((int)real(c_token), stderr, FALSE);
- c_token++;
- }
- }
- else if (almost_equals(c_token,"li$ne") || almost_equals(c_token,"ar$row")) {
- (void) putc('\n',stderr);
- c_token++;
- if (END_OF_COMMAND)
- show_arrow(0, stderr, FALSE);
- else {
- show_arrow((int)real(c_token), stderr, FALSE);
- c_token++;
- }
- }
- else if (almost_equals(c_token,"bas$e")) {
- (void) putc('\n',stderr);
- show_base();
- c_token++;
- }
- else if (almost_equals(c_token,"fr$ame")) {
- (void) putc('\n',stderr);
- show_border();
- c_token++;
- }
- else if (almost_equals(c_token,"for$mat")) {
- (void) putc('\n',stderr);
- show_format();
- c_token++;
- }
- else if (almost_equals(c_token,"fon$t")) {
- (void) putc('\n',stderr);
- show_font();
- c_token++;
- }
- else if (almost_equals(c_token,"cl$ockwise")) {
- (void) putc('\n',stderr);
- show_clock(TRUE);
- show_clock(FALSE);
- c_token++;
- }
- else if (almost_equals(c_token,"cu$stomized")) {
- (void) putc('\n',stderr);
- show_custom();
- c_token++;
- }
- else if (almost_equals(c_token,"ex$plode")) {
- (void) putc('\n',stderr);
- show_explode();
- c_token++;
- }
- else if (almost_equals(c_token,"gr$avitation")) {
- (void) putc('\n',stderr);
- show_gravity();
- c_token++;
- }
- else if (almost_equals(c_token,"h$ighlight")) {
- (void) putc('\n',stderr);
- show_HLset();
- c_token++;
- }
- else if (almost_equals(c_token,"i$nput")) {
- (void) putc('\n',stderr);
- show_input();
- c_token++;
- }
- else if (almost_equals(c_token,"of$fsets")) {
- (void) putc('\n',stderr);
- show_offsets();
- c_token++;
- }
- else if (almost_equals(c_token,"o$utput")) {
- (void) putc('\n',stderr);
- show_output();
- c_token++;
- }
- else if (almost_equals(c_token,"sa$mples")) {
- (void) putc('\n',stderr);
- show_samples();
- c_token++;
- }
- else if (almost_equals(c_token,"st$yle")) {
- (void) putc('\n',stderr);
- c_token++;
- show_style();
- }
- else if (almost_equals(c_token,"si$ze")) {
- (void) putc('\n',stderr);
- c_token++;
- show_size();
- }
- else if (almost_equals(c_token,"te$rminal")) {
- (void) putc('\n',stderr);
- show_term();
- c_token++;
- }
- else if (almost_equals(c_token,"ti$tle")) {
- (void) putc('\n',stderr);
- show_title();
- c_token++;
- }
- else if (almost_equals(c_token,"th$reshold")) {
- (void) putc('\n',stderr);
- show_tresh();
- c_token++;
- }
- else if (almost_equals(c_token,"tr$uncate")) {
- (void) putc('\n',stderr);
- show_trunc();
- c_token++;
- }
- else if (almost_equals(c_token,"w$idth")) {
- (void) putc('\n',stderr);
- show_width();
- c_token++;
- }
- else if (almost_equals(c_token,"ve$rsion")) {
- show_version();
- c_token++;
- }
- else if (almost_equals(c_token,"rad$ius")) {
- (void) putc('\n',stderr);
- show_radius();
- c_token++;
- }
- else if (almost_equals(c_token,"r$ange")) {
- (void) putc('\n',stderr);
- show_range();
- c_token++;
- }
- else if (almost_equals(c_token,"z$ero") ||
- almost_equals(c_token,"eps$ilon")) {
- (void) putc('\n',stderr);
- show_zero();
- c_token++;
- }
- else if (almost_equals(c_token,"g$eneral")) { /* no more !!! */
- c_token++;
- show_version();
- show_input();
- show_custom();
- show_range();
- show_label();
- show_trunc();
- show_output();
- show_term();
- show_size();
- show_offsets();
- show_border();
- show_font();
- show_title();
- show_labels(0, stderr, FALSE);
- show_arrow(0, stderr, FALSE);
- show_logscale();
- show_format();
- show_zero();
- show_HLset();
- show_style();
- }
- else if (almost_equals(c_token,"bar$charts")) {
- c_token++;
- show_version();
- show_style();
- fprintf(stderr,"\n\tsettings for barcharts (any bar style):\n\n");
- show_base();
- show_width();
- show_autoscale();
- show_gravity();
- show_clock(FALSE);
- }
- else if (almost_equals(c_token,"pie$charts")) {
- c_token++;
- show_version();
- show_style();
- fprintf(stderr,"\n\tsettings for piecharts:\n\n");
- show_clock(TRUE);
- show_explode();
- show_radius();
- show_tresh();
- show_samples();
- }
- else if (almost_equals(c_token,"a$ll")) {
- c_token++;
- show_version();
- show_input();
- show_custom();
- show_range();
- show_label();
- show_trunc();
- show_output();
- show_term();
- show_size();
- show_offsets();
- show_border();
- show_font();
- show_title();
- show_labels(0, stderr, FALSE);
- show_arrow(0, stderr, FALSE);
- show_logscale();
- show_format();
- show_zero();
- show_HLset();
- show_style();
- show_base();
- show_width();
- show_autoscale();
- show_gravity();
- show_clock(FALSE); /* bars */
- show_clock(TRUE); /* pies */
- show_explode();
- show_radius();
- show_tresh();
- show_samples();
- }
- else
- int_error(
- "valid show options: 'all', 'scale', 'base', 'font'\n\
- 'customized', 'explode', 'gravitation', 'highlight',\n\
- 'input', 'logscale', 'offsets', 'output', 'label',\n\
- 'samples', 'style', 'terminal', 'version', 'range',\n\
- 'radius', 'clockwise', 'width', 'zero/epsilon', 'frame',\n\
- 'size', 'general', 'barcharts', 'piecharts', 'format',\n\
- 'threshold', 'truncate', 'line', 'arrow', 'autolabeling'",
- c_token);
- screen_ok = FALSE;
- (void) putc('\n',stderr);
- }
-
-
- load_offsets (a, b, c, d)
- double *a, *b, *c, *d;
- {
- *a = real (c_token); /* loff value */
- if (*a >= 100.0 && d)
- int_error("value <0,100) expected",c_token);
- c_token++;
- if (equals(c_token,","))
- c_token++;
- if (END_OF_COMMAND)
- return;
-
- *b = real (c_token); /* roff value */
- if (*b >= 100.0 && d)
- int_error("value <0,100) expected",c_token);
- c_token++;
- if (equals(c_token,","))
- c_token++;
- if (END_OF_COMMAND)
- return;
-
- *c = real (c_token); /* toff value */
- if (*c >= 100.0 && d)
- int_error("value <0,100) expected",c_token);
- c_token++;
-
- if (!d) return;
- if (equals(c_token,","))
- c_token++;
- if (END_OF_COMMAND)
- return;
-
- *d = real (c_token); /* boff value */
- if (*d >= 100.0)
- int_error("value <0,100) expected",c_token);
- c_token++;
- }
-
-
- load_range(a,b)
- int *a, *b;
- {
- if (equals(c_token,"]"))
- return; /* no change */
- if (END_OF_COMMAND) {
- int_error("starting range value or ':' expected",c_token);
- } else if (!equals(c_token,"to") && !equals(c_token,":")) {
- *a = (int)real(c_token);
- c_token++;
- }
- else *a = 0; /* from the very begining */
- if (!equals(c_token,"to") && !equals(c_token,":"))
- int_error("':' expected",c_token);
- c_token++;
- if (!equals(c_token,"]")) {
- *b = (int)real(c_token);
- c_token++;
- }
- else *b = -1; /* to infinity */
- }
-
-
- plotrequest(xplot)
- BOOLEAN xplot;
- {
-
- if (!term) /* unknown */
- int_error("use 'set term' to set terminal type first",c_token);
-
- if (log_y && base<1.0 && data_style != PIECHART)
- int_error("base for bars out of range for logscale",NO_CARET);
-
- if (equals(c_token,"[")) {
- c_token++;
- load_range(&xmin,&xmax);
- if (!equals(c_token,"]"))
- int_error("']' expected",c_token);
- c_token++;
- if (xmax != -1 && xmax < xmin)
- int_error("given range is empty",NO_CARET);
- }
-
- eval_plots(xplot);
- }
-
- int missing(s)
- char *s;
- /* check if s represents a missing value (spaces and dot) */
- {
- char *p = s + strlen(s) - 1;
- if (!s || !*s)
- return(1);
- while (isspace(*s)) s++;
- if (s == p && *s == '.')
- return(1);
- else
- return(0);
- }
-
- get_data(this_plot,this_style)
- struct dfile *this_plot;
- enum INP_STYLE this_style;
- {
- static char data_file[MAX_LINE_LEN+1], line[MAX_LINE_LEN+1];
- register int i, l_num, ob_num, scanval;
- register FILE *fp;
- double x;
- struct chunk *chn;
- char *labpt;
- int chsiz = CH_INIT_SIZE;
- int lablen, aux;
-
- quote_str(data_file, c_token);
- m_quote_capture(&(this_plot->fname), c_token, c_token);
-
- chn = (struct chunk *) alloc((unsigned)sizeof(struct chunk), data_file);
- chn->next = NULL; /* in case of further errors */
- chn->dval = NULL;
- chn->vlbl = (char **) NULL;
- this_plot->data = chn;
- this_plot->chunks = 1;
- if (xmin != -1 && xmax != -1) /* known number of data */
- chsiz = xmax - xmin + 1;
- chn->dval = (vreal *) alloc((unsigned)chsiz*sizeof(vreal), data_file);
- chn->used = 0;
- if (this_style != CUSTOMD || label_plac.from != -1) { /* labels expected */
- chn->vlbl = (char **) alloc((unsigned)chsiz*sizeof(char *), data_file);
- for (i=0; i<chsiz; i++)
- chn->vlbl[i] = (char *) NULL;
- }
- this_plot->d_min = VERYLARGE;
- this_plot->d_max = -VERYLARGE;
- this_plot->points = 0;
- this_plot->makeHL = HL_NON;
- this_plot->labels = TRUE; /* label autogenerating may be possible */
-
- if (!(fp = fopen(data_file, "r")))
- os_error("can't open data file", c_token);
-
- l_num = 0;
- ob_num = -1; /* will be incremented before any operation */
- i = -1;
-
- while (fgets(line, MAX_LINE_LEN, fp)) { /* REWRITE ALL !!! */
- l_num++;
- if (is_comment(line[0]) && this_style != CUSTOMD) /* label can be on any position, incl. 1st column */
- continue; /* ignore comments */
-
- i++;
- if (i<xmin) continue; /* still out of range */
- if (xmax != -1 && i>xmax) break; /* don't even read the rest of file */
-
- line[strlen(line)-1] = '\0'; /* get rid of '\n' */
- ob_num++;
- if (ob_num==chsiz) { /* open new chunk */
- chn->next = (struct chunk *) alloc((unsigned)sizeof(struct chunk), data_file);
- chn = chn->next;
- chn->next = NULL; /* in case of further errors */
- chn->dval = NULL;
- chn->vlbl = (char **) NULL;
- this_plot->chunks++;
- this_plot->points += chsiz; /* chunkful of points */
- chsiz *= 2; /* probably the optimal allocation step */
- chn->dval = (vreal *) alloc((unsigned)chsiz*sizeof(vreal), (char *)NULL);
- if (!chn->dval)
- (void) fclose(fp),
- int_error("out of memory",c_token);
- chn->used = 0; /* this one */
- if (this_style != CUSTOMD || label_plac.from != -1) { /* labels expected */
- chn->vlbl = (char **) alloc((unsigned)chsiz*sizeof(char *), (char *)NULL);
- if (!chn->vlbl)
- (void) fclose(fp),
- int_error("out of memory",c_token++);
- else {
- int ii;
- for (ii=0; ii<chsiz; ii++)
- chn->vlbl[ii] = (char *) NULL;
- }
- }
- ob_num = 0;
- }
-
- if (!*line && this_style != CUSTOMD) { /* empty data == missing value. not in SAS */
- chn->dval[ob_num] = VERYLARGE;
- if (chn->vlbl)
- chn->vlbl[ob_num] = (char *) NULL;
- chn->used++;
- continue;
- }
-
- /* so here we go. now consider input format */
- switch (this_style) {
- case PRIVATE:
- scanval = sscanf(line,"%lf",&x);
- if (scanval == 1) {
- for (labpt = line; *labpt && isspace(*labpt); labpt++) ;
- while (*labpt && !isspace(*labpt)) labpt++;
- lablen = strlen(labpt); /* initialy */
- }
- break;
- case GNUPLOT:
- scanval = sscanf(line,"%*lf %lf",&x);
- if (scanval == 1) {
- for (aux=0; isspace(line[aux]); aux++);
- labpt = line + aux;
- for (lablen=0; !isspace(line[aux++]); lablen++) ;
- }
- else labpt=NULL, scanval = sscanf(line,"%lf",&x);
- break;
- case CUSTOMD:
- if (strlen(line) < data_place.from) {
- scanval = 0; /* generate error */
- break;
- }
- labpt = line + data_place.from;
- if (data_place.upto == -1 || data_place.upto >= strlen(line))
- if (missing(labpt))
- x = VERYLARGE;
- else
- scanval = sscanf(labpt,"%lf",&x);
- else {
- aux = line[data_place.upto];
- line[data_place.upto] = '\0';
- if (missing(labpt))
- x = VERYLARGE;
- else
- scanval = sscanf(labpt,"%lf",&x);
- line[data_place.upto] = aux;
- }
- if (x == VERYLARGE) { /* missing value detected, or unplottable anyway */
- chn->dval[ob_num] = VERYLARGE;
- if (chn->vlbl)
- chn->vlbl[ob_num] = (char *) NULL;
- chn->used++;
- continue;
- }
- if (label_plac.from >= strlen(line) || label_plac.from == -1)
- labpt = NULL;
- else {
- labpt = line + label_plac.from;
- if (label_plac.upto == -1 || label_plac.upto >= strlen(line))
- lablen = strlen(labpt);
- else
- lablen = label_plac.upto - label_plac.from - 1;
- }
- break;
- }
-
- if (scanval != 1) { /* can be also EOF for empty line */
- (void) sprintf(line, "bad data on line %d", l_num);
- (void) fclose(fp);
- int_error(line,c_token);
- }
-
- if (x<0.0 && data_style == PIECHART ||
- x<1.0 && data_style != PIECHART && log_y) {
- (void) fclose(fp);
- (void) sprintf(line,"unplotable data on line %d",l_num);
- int_error(line,c_token);
- }
-
- if (log_y) x = log10(x);
-
- chn->dval[ob_num] = (vreal) x;
- if (x<this_plot->d_min) this_plot->d_min = (vreal) x;
- if (x>this_plot->d_max) this_plot->d_max = (vreal) x; /* without 'else', I know */
-
- if (labpt && *labpt && lablen && strunc!=0) { /* copy existing label -- ignore if empty */
- char *q;
- /* remove meaningless spaces */
- while (isspace(*labpt)) labpt++, lablen--;
- while (isspace(labpt[lablen])) lablen--;
- if (strunc>0 && strunc<lablen)
- lablen = strunc;
- if (!lablen) /* truncated to zero */
- chn->vlbl[ob_num] = (char *) NULL;
- else {
- if (!(q = alloc((unsigned) lablen+1, (char *)NULL))) {
- (void) fclose(fp);
- int_error("out of memory",c_token);
- }
- (void) strncpy(q,labpt,lablen);
- q[lablen] = '\0';
- chn->vlbl[ob_num] = q;
- this_plot->labels = FALSE; /* cannot autogenerate labels if some exist */
- }
- }
- else
- chn->vlbl[ob_num] = (char *) NULL;
-
- chn->used++;
- } /* while */
-
- (void) fclose(fp);
- if (i<xmin)
- int_error("too few data",c_token);
-
- this_plot->points += chn->used;
-
- }
-
- eval_plots(xplot)
- BOOLEAN xplot;
- {
- struct dfile *dp = &data_head, *tail;
- enum INP_STYLE in_st;
-
- data_head.d_min = VERYLARGE; data_head.d_max = -VERYLARGE;
- data_head.points = data_head.chunks = 0;
- if (data_head.data) free((char *)data_head.data);
- data_head.data = NULL;
- destroy(data_head.dnxt);
- data_head.dnxt = (struct dfile *) NULL;
- data_head.makeHL = HLitem;
- data_head.labels = auto_label;
-
- while (TRUE) {
- if (END_OF_COMMAND)
- int_error("data file to plot expected",c_token);
- if (equals(c_token,"(")) {
- c_token++;
- in_st = get_input();
- if (END_OF_COMMAND || !equals(c_token,")"))
- int_error("expected ')'",c_token);
- c_token++;
- }
- else
- in_st = inp_style;
- if (in_st == CUSTOMD && data_place.from == -1)
- int_error("Customized input format not defined. Use 'set customized'",NO_CARET);
-
- if (END_OF_COMMAND || !isstring(c_token))
- int_error("data file to plot expected",c_token);
- tail = (struct dfile *) alloc((unsigned int) sizeof(struct dfile), "data");
- tail->fname = NULL;
- tail->data = NULL;
- tail->dnxt = NULL;
- dp->dnxt = tail; /* to free all memory on error */
-
- get_data(tail,in_st);
-
- c_token++;
- dp = tail;
- data_head.chunks++; /* here we count overall number of files */
- if (data_style != ABARS && data_style != PIECHART || xplot) /* if (ABARS || PIECHART => xplot) */
- data_head.labels = data_head.labels && dp->labels; /* is making labels sensible or not ? */
- /* else this serves different purpose */
- if (data_head.points < dp->points)
- data_head.points = dp->points; /* ... and maximal number of points */
- if (data_head.d_min > dp->d_min)
- data_head.d_min = dp->d_min; /* minimum ... */
- if (data_head.d_max < dp->d_max)
- data_head.d_max = dp->d_max; /* and maximum */
-
- if (almost_equals(c_token,"a$s")) {
- c_token++;
- if (END_OF_COMMAND || !isstring(c_token))
- int_error("name in quotes expected", c_token);
- else {
- m_quote_capture(&(dp->fname), c_token, c_token);
- c_token++;
- }
- }
-
- if (almost_equals(c_token,"h$ighlighting")) {
- c_token++;
- dp->makeHL = get_HL();
- }
-
- if (END_OF_COMMAND)
- break;
- else if (equals(c_token,","))
- c_token++;
- else
- int_error("expected ','",c_token);
- }
-
- if (data_head.d_min == VERYLARGE || data_head.d_max == -VERYLARGE)
- int_error("all points undefined, nothing to draw",NO_CARET);
-
- if (data_head.chunks > 1) { /* reserve space for xpointers structure */
- /* do it here, to avoid memory management in graphics.c */
- data_head.data = (struct chunk *) alloc((unsigned)data_head.chunks*sizeof(struct xptr), "data");
- }
-
- capture(replot_line,plot_token,c_token);
- do_plot(xplot,data_style,xmin<=0?0:xmin);
- }
-
- done(status)
- int status;
- {
- if (term && term_init)
- (*term_tbl[term].reset)();
- #ifdef VMS
- vms_reset();
- #endif
- exit(status);
- }
-
- #ifdef MSDOS
- #ifndef __TURBOC__ /* Turbo C already has sleep() */
- #ifndef __ZTC__ /* ZTC already has usleep() */
- /* kludge to provide sleep() for msc 5.1 */
- void sleep(delay)
- unsigned int delay;
- {
- unsigned long time_is_up;
- time_is_up = time(NULL) + (unsigned long) delay;
- while (time(NULL)<time_is_up)
- /* wait */ ;
- }
- #endif /* not ZTC */
- #endif /* not TURBOC */
- #endif /* MSDOS */
-
-
- /* Support for input, shell, and help for various systems */
-
- #ifdef vms
-
- #include <descrip.h>
- #include <rmsdef.h>
- #include <errno.h>
-
- extern lib$get_input(), lib$put_output();
-
- int vms_len;
-
- unsigned int status[2] = {1, 0};
-
- static char help[MAX_LINE_LEN+1] = "fchart";
-
- $DESCRIPTOR(prompt_desc,PROMPT);
- $DESCRIPTOR(line_desc,input_line);
-
- $DESCRIPTOR(help_desc,help);
- $DESCRIPTOR(helpfile_desc,"FCHART$HELP");
-
- read_line(prompt)
- char *prompt;
- {
- int more, start=0;
- char exp_prompt = EXP_PROMPT;
- prompt_desc.dsc$w_length = strlen (prompt);
- prompt_desc.dsc$a_pointer = prompt;
- do {
- line_desc.dsc$w_length = MAX_LINE_LEN - start;
- line_desc.dsc$a_pointer = &input_line[start];
- switch(status[1] = lib$get_input(&line_desc, &prompt_desc, &vms_len)){
- case RMS$_EOF:
- done(IO_SUCCESS); /* ^Z isn't really an error */
- break;
- case RMS$_TNS: /* didn't press return in time */
- vms_len--; /* skip the last character */
- break; /* and parse anyway */
- case RMS$_BES: /* Bad Escape Sequence */
- case RMS$_PES: /* Partial Escape Sequence */
- sys$putmsg(status);
- vms_len = 0; /* ignore the line */
- break;
- case SS$_NORMAL:
- break; /* everything's fine */
- default:
- done(status[1]); /* give the error message */
- }
- start += vms_len;
- input_line[start] = '\0';
- if (input_line[start-1] == '\\') {
- /* Allow for a continuation line. */
- prompt_desc.dsc$w_length = strlen (exp_prompt);
- prompt_desc.dsc$a_pointer = exp_prompt;
- more = 1;
- --start;
- }
- else {
- line_desc.dsc$w_length = strlen(input_line);
- line_desc.dsc$a_pointer = input_line;
- more = 0;
- }
- } while (more);
- }
-
-
- do_help()
- {
- help_desc.dsc$w_length = strlen(help);
- if ((vaxc$errno = lbr$output_help(lib$put_output,0,&help_desc,
- &helpfile_desc,0,lib$get_input)) != SS$_NORMAL)
- os_error("can't open FCHART$HELP");
- }
-
-
- do_shell()
- {
- if ((vaxc$errno = lib$spawn()) != SS$_NORMAL) {
- os_error("spawn error",NO_CARET);
- }
- }
-
-
- do_system()
- {
- input_line[0] = ' '; /* an embarrassment, but... */
-
- if ((vaxc$errno = lib$spawn(&line_desc)) != SS$_NORMAL)
- os_error("spawn error",NO_CARET);
-
- (void) putc('\n',stderr);
- }
-
- #else /* vms */
-
- /* do_help: (not VMS, although it would work)
- * Give help to the user.
- * It parses the command line into helpbuf and supplies help for that
- * string. Then, if there are subtopics available for that key,
- * it prompts the user with this string. If more input is
- * given, do_help is called recursively, with the argument the index of
- * null character in the string. Thus a more specific help can be
- * supplied. This can be done repeatedly.
- * If null input is given, the function returns, effecting a
- * backward climb up the tree.
- * David Kotz (dfk@cs.duke.edu) 10/89
- */
- do_help()
- {
- static char helpbuf[MAX_LINE_LEN] = "";
- static char prompt[MAX_LINE_LEN] = "";
- int base; /* index of first char AFTER help string */
- int len; /* length of current help string */
- BOOLEAN more_help;
- BOOLEAN only; /* TRUE if only printing subtopics */
- int subtopics; /* 0 if no subtopics for this topic */
- int start; /* starting token of help string */
- char *help_ptr; /* name of help file */
-
- if ( (help_ptr = getenv("FCHARTHELP")) == (char *)NULL )
- /* if can't find environment variable then just use HELPFILE */
- help_ptr = HELPFILE;
-
- len = base = strlen(helpbuf);
-
- /* find the end of the help command */
- for (start = c_token; !(END_OF_COMMAND); c_token++) ;
- /* copy new help input into helpbuf */
- if (len > 0)
- helpbuf[len++] = ' '; /* add a space */
- capture(helpbuf+len, start, c_token-1);
- squash_spaces(helpbuf+base); /* only bother with new stuff */
- lower_case(helpbuf+base); /* only bother with new stuff */
- len = strlen(helpbuf);
-
- /* now, a lone ? will print subtopics only */
- if (strcmp(helpbuf + (base ? base+1 : 0), "?") == 0) {
- /* subtopics only */
- subtopics = 1;
- only = TRUE;
- helpbuf[base] = '\0'; /* cut off question mark */
- } else {
- /* normal help request */
- subtopics = 0;
- only = FALSE;
- }
-
- switch ( help(helpbuf, help_ptr, &subtopics)) {
- case H_FOUND: {
- /* already printed the help info */
- /* subtopics now is true if there were any subtopics */
- screen_ok = FALSE;
-
- do {
- if (subtopics && !only) {
- /* prompt for subtopic with current help string */
- if (len > 0)
- (void) sprintf(prompt, "Subtopic of %s: ", helpbuf);
- else
- (void) strcpy(prompt, "Help topic: ");
- read_line(prompt);
- num_tokens = scanner(input_line);
- c_token = 0;
- more_help = !(END_OF_COMMAND);
- if (more_help)
- /* base for next level is all of current helpbuf */
- do_help();
- } else
- more_help = FALSE;
- } while(more_help);
-
- break;
- }
- case H_NOTFOUND: {
- printf("Sorry, no help for '%s'\n", helpbuf);
- break;
- }
- case H_ERROR: {
- perror(help_ptr);
- break;
- }
- default: { /* defensive programming */
- int_error("Impossible case in switch\n", NO_CARET);
- /* NOTREACHED */
- }
- }
-
- helpbuf[base] = '\0'; /* cut it off where we started */
- }
-
- do_system()
- {
- if (system(input_line + 1))
- os_error("system() failed",NO_CARET);
- }
-
- #ifdef MSDOS
-
- read_line(prompt)
- char *prompt;
- {
- int last, start = 0;
- BOOLEAN more;
-
- #ifndef __ZTC__
- if (interactive) { /* if interactive use console IO so CED will work */
- cputs(prompt);
- do {
- input_line[start] = MAX_LINE_LEN - start - 1;
- cgets(&(input_line[start]));
- (void) putc('\n',stderr);
- if (input_line[start+2] == 26) {
- /* end-of-file */
- (void) putc('\n',stderr);
- input_line[start] = '\0';
- if (start > 0) /* don't quit yet - process what we have */
- more = FALSE;
- else {
- (void) putc('\n',stderr);
- done(IO_SUCCESS);
- /* NOTREACHED */
- }
- } else {
- /* normal line input */
- register i = start;
- while ( (input_line[i] = input_line[i+2]) != (char)NULL )
- i++; /* yuck! move everything down two characters */
-
- last = strlen(input_line) - 1;
- if (last + 1 >= MAX_LINE_LEN)
- int_error("Input line too long",NO_CARET);
-
- if (input_line[last] == '\\') { /* line continuation */
- start = last;
- more = TRUE;
- } else
- more = FALSE;
- }
- if (more && isatty(fileno(stdin)))
- cputs(EXP_PROMPT);
- } while(more);
- }
- else { /* not interactive */
- #endif /* not ZTC */
- if (interactive)
- fputs(prompt,stderr);
- do {
- /* grab some input */
- if ( fgets(&(input_line[start]), MAX_LINE_LEN - start, stdin)
- == (char *)NULL ) {
- /* end-of-file */
- if (interactive)
- (void) putc('\n',stderr);
- input_line[start] = '\0';
- if (start > 0) /* don't quit yet - process what we have */
- more = FALSE;
- else
- done(IO_SUCCESS); /* no return */
- } else {
- /* normal line input */
- last = strlen(input_line) - 1;
- if (input_line[last] == '\n') { /* remove any newline */
- input_line[last] = '\0';
- /* Watch out that we don't backup beyond 0 (1-1-1) */
- if (last > 0) --last;
- } else if (last+1 >= MAX_LINE_LEN)
- int_error("Input line too long",NO_CARET);
-
- if (input_line[last] == '\\') { /* line continuation */
- start = last;
- more = TRUE;
- } else
- more = FALSE;
- }
- if (more && interactive)
- fputs(EXP_PROMPT, stderr);
- } while(more);
- #ifndef __ZTC
- }
- #endif
-
- #ifdef FILIP
- input_line[0] = MAX_LINE_LEN - 1;
- cputs(PROMPT);
- cgets(input_line); /* console input so CED will work */
- (void) putc('\n',stderr);
- if (input_line[2] == 26) {
- (void) putc('\n',stderr); /* end-of-file */
- done(IO_SUCCESS);
- }
-
- i = 0;
- while (input_line[i] = input_line[i+2])
- i++; /* yuck! move everything down two characters */
- #endif
- }
-
-
- do_shell()
- {
- register char *comspec;
- if (!(comspec = getenv("COMSPEC")))
- comspec = "\command.com";
- if (spawnl(P_WAIT,comspec,NULL) == -1)
- os_error("unable to spawn shell",NO_CARET);
- }
-
- #else /* MSDOS */
- /* plain old Unix */
-
- read_line(prompt)
- char *prompt;
- {
- int start=0, last=0;
- BOOLEAN more;
-
- if (interactive) fputs(prompt,stderr);
- do {
- if (!fgets(&input_line[start], MAX_LINE_LEN-start, stdin)) {
- if (interactive)
- (void) putc('\n',stderr); /* end-of-file */
- input_line[start] = '\0';
- if (start > 0) /* don't quit yet - process what we have */
- more = FALSE;
- else
- done(IO_SUCCESS); /* no return */
- }
- else { /* normal line input */
- last = strlen(input_line)-1;
- if (input_line[last] == '\n') { /* remove any newline */
- input_line[last] = '\0';
- /* Watch out that we don't backup beyond 0 (1-1-1) */
- if (last > 0) --last;
- }
- else if (last+1 >= MAX_LINE_LEN)
- int_error("Input line too long",NO_CARET);
-
- if (input_line[last] == '\\') { /* line continuation */
- start = last;
- more = TRUE;
- } else
- more = FALSE;
- }
- if (more && interactive) fputs(EXP_PROMPT,stderr);
- } while (more);
- }
-
- #ifdef VFORK
-
- do_shell()
- {
- register char *shell;
- register int p;
- static int execstat;
- if (!(shell = getenv("SHELL")))
- shell = SHELL;
- if ((p = vfork()) == 0) {
- execstat = execl(shell,shell,NULL);
- _exit(1);
- } else if (p == -1)
- os_error("vfork failed",c_token);
- else
- while (wait(NULL) != p)
- ;
- if (execstat == -1)
- os_error("shell exec failed",c_token);
- (void) putc('\n',stderr);
- }
- #else /* VFORK */
-
- #define EXEC "exec "
- do_shell()
- {
- static char exec[100] = EXEC;
- register char *shell;
- if (!(shell = getenv("SHELL")))
- shell = SHELL;
-
- if (system(strncpy(&exec[sizeof(EXEC)-1],shell,
- sizeof(exec)-sizeof(EXEC)-1)))
- os_error("system() failed",NO_CARET);
-
- (void) putc('\n',stderr);
- }
- #endif /* VFORK */
- #endif /* MSDOS */
- #endif /* vms */
-